﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IoTEdge.Grpc.Server.AmrEx;
using MQTTnet;
using MQTTnet.Client;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace IoTEdge.Grpc.Server
{
    public class BackgroundAmrExCollectPlugin : BackgroundService
    {
        NLog.ILogger logger = LogManager.GetCurrentClassLogger();
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var task = Task.Run(async () =>
            {
                var url = Environment.GetEnvironmentVariable("IoTEdgeAmrAddr", EnvironmentVariableTarget.Machine);
                if (url == null)
                {
                    logger.Error("AMR服务器地址未设置，请检查系统环境变量[IoTEdgeAmrAddr]!");
                    return;
                }
                var urls = url.Split(":");
                if (urls.Length != 2)
                {
                    logger.Error("服务器地址不合法 " + url);
                    return;
                }
                var mqtturl = Environment.GetEnvironmentVariable("IoTEdgeMQTTAddr", EnvironmentVariableTarget.Machine);
                if (mqtturl == null)
                {
                    logger.Error("MQTT服务器地址未设置，请检查系统环境变量[IoTEdgeMQTTAddr]!");
                    return;
                }
                var amrauth = Environment.GetEnvironmentVariable("IoTEdgeAmrAuth", EnvironmentVariableTarget.Machine);
                if (amrauth == null)
                {
                    logger.Error("Amr服务器授权信息未设置，请检查系统环境变量[IoTEdgeAmrAuth]!");
                    return;
                }
                var auths = amrauth.Split(":"); 
                var client = new MqttFactory().CreateMqttClient();
                var mqttClientOptions = new MqttClientOptionsBuilder()
                .WithTcpServer($"{mqtturl}")
                .Build(); 
                try
                {
                    var conre = await client.ConnectAsync(mqttClientOptions);
                    if (conre.ResultCode != MqttClientConnectResultCode.Success)
                    {
                        logger.Error($"未能连接至MQTT服务器[{mqtturl}]，请检查配置！");
                        return;
                    }
                }
                catch (Exception ex)
                {
                    logger.Error($"未能连接至MQTT服务器，请检查配置！" + ex.Message);
                    return;
                }
                var resub = await client.SubscribeAsync("AmrStop");
                client.ApplicationMessageReceivedAsync += async (x) =>
                {
                    if (x.ApplicationMessage.Topic == "AmrStop")
                    {
                        var msg = Encoding.UTF8.GetString(x.ApplicationMessage.PayloadSegment);
                        var obj = (JObject)JsonConvert.DeserializeObject(msg);
                        try
                        {
                            var current = obj["services"]["stop"]["properties"]["AMRstop"]["value"].ToString();
                            if (current != null)
                            {
                                if (current.ToString() == "1")
                                {
                                    for (int i = 0; i < 8; i++)
                                    {
                                        try
                                        {
                                            var reslist = await AmrExLib.GetTaskChainId(urls[0], urls[1], auths[0], auths[1]);
                                            await Task.Delay(100);
                                            await AmrExLib.StopAmrByTaskChainId(urls[0], urls[1], auths[0], auths[1], reslist);
                                            await Task.Delay(1000);
                                        }
                                        catch (Exception ex)
                                        {
                                            logger.Error($"急停请求出现错误，请检查配置！" + ex.Message);
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            logger.Error($"无法获取到操作信息" + ex.Message);
                        }
                    } 
                    await Task.Delay(100);
                };
            });
            await Task.WhenAll(task);
        }
    }
}
